using System;
using System.Collections;
using System.Collections.Generic;

namespace Decision_Tree
{
	/* Types of Decision Tree Nodes */
	public class DecisionTreeNode
	{
		public Attribute testAttribute = Attribute.DEFAULT;
		public Dictionary<bool, DecisionTreeNode> daughters = new Dictionary<bool, DecisionTreeNode>();
		public Actions action = Actions.DEFAULT;
		
		public int nodeId = 0;
		public int nodeParent = 0;
		public static int nodeCount = 0;
		
		public virtual DecisionTreeNode makeDecision(Knowledge agent)
		{
			throw new NotImplementedException();
			//return null;
		}
		
		public virtual void print()
		{
			Console.WriteLine("\n--------------NODE " + nodeId + "-------------");
			Console.WriteLine("Parent " + nodeParent);
			if(testAttribute == Attribute.DEFAULT) {
				Console.WriteLine("MyAction: ["+action+"]");
			} else {
				Console.WriteLine("MyAttrib: "+testAttribute);
				Console.Write("MyKids: ");
				foreach (KeyValuePair<bool, DecisionTreeNode> cur in daughters)
				{
					if(cur.Value.testAttribute == Attribute.DEFAULT)
						Console.Write("("+cur.Key+"): "+cur.Value.nodeId + " " + cur.Value.action+" | ");
					else
						Console.Write("("+cur.Key+"): "+cur.Value.nodeId + " " + cur.Value.testAttribute+" | ");
				}
				Console.WriteLine();

			}
						
			foreach (KeyValuePair<bool, DecisionTreeNode> cur in daughters)
			{
				cur.Value.print();
			}	
		}
	}

	public class Decision : DecisionTreeNode
	{
		public DecisionTreeNode getBranch(Knowledge agent)
		{
			return daughters[agent.valueForAttribute(testAttribute)];
		}
		
		public override DecisionTreeNode makeDecision(Knowledge agent)
		{
			DecisionTreeNode branch = this.getBranch(agent);
			return branch.makeDecision(agent);
		}
		
		public Decision()
		{
			nodeCount++;
			nodeId = nodeCount;
		}
	}	
	
	public class Action : DecisionTreeNode
	{
		public override DecisionTreeNode makeDecision(Knowledge agent)
		{
			return this;
		}
		
		public Action()
		{
			nodeCount++;
			nodeId = nodeCount;
		}
	}	
}